#include "Fps.h"
#include "D3DUtil.h"
#include <stdio.h>
#include <d3dx9.h>


class FPSDisplayerImpl
{
private:
	IDirect3DDevice9* m_device;
	ID3DXFont*        m_font;
	DWORD             m_frameCount;
	float             m_timeElapsed;
	float             m_fps;
	char              m_fpsString[32];

public:
	static const int k_Width = 640;
	static const int k_Height = 480;

	FPSDisplayerImpl(IDirect3DDevice9* device) 
		: m_device(device),
		  m_font(0), 
		  m_frameCount(0), 
		  m_timeElapsed(0.0f),
		  m_fps(0.0f)
	{
		m_fpsString[0] = '\0';

		// Init a LOGFONT structure that describe the font
		// we want to create.
		D3DXFONT_DESC  df;
		::ZeroMemory(&df, sizeof(D3DXFONT_DESC));

		df.Height           = 25; // in logic units
		df.Width            = 12;
		df.Weight           = 500;
		df.MipLevels        = D3DX_DEFAULT;
		df.Italic           = false;
		df.CharSet          = DEFAULT_CHARSET;
		df.OutputPrecision  = 0;
		df.Quality          = 0;
		df.PitchAndFamily   = 0;
		strcpy(df.FaceName, "Times New Roman");

		// Create an ID3DXFont based on 'lf'
		if(FAILED(D3DXCreateFontIndirect(m_device, &df, &m_font)))
		{
			::MessageBox(0, "D3DXCreateFontIndirect() - FAILED", 0, 0);
			::PostQuitMessage(0);
		}
	}


	~FPSDisplayerImpl()
	{
		d3dutil::Release<ID3DXFont*>(m_font);
		m_device = 0;
	}

	void DrawFPSTextImpl(float timeDelta)
	{
		m_frameCount++;
		m_timeElapsed += timeDelta;

		if (m_timeElapsed >= 1.0f)
		{
			m_fps = (float)m_frameCount / m_timeElapsed;

			sprintf_s(m_fpsString, 31, "FPS: %f", m_fps);
			m_timeElapsed = 0.0f;
			m_frameCount  = 0;
		}		

		RECT  rect = {0, 0, k_Width, k_Height};
		m_font->DrawText(
			NULL,
			m_fpsString,
			-1,
			&rect,
			DT_TOP | DT_LEFT,
			0xff000000);	
	}
};


void FPSDisplayer::DrawFPSText(float timeDelta)
{
	m_impl->DrawFPSTextImpl(timeDelta);
}

FPSDisplayer::FPSDisplayer( IDirect3DDevice9* device ) : m_device(device)
{
	m_impl = new FPSDisplayerImpl(m_device);
}

FPSDisplayer::~FPSDisplayer()
{
	delete m_impl;
	m_impl = 0;
}